﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Tenebrous_Manor
{
    class Player
    {
        KeyboardState keyboard_old;

        SpriteEffects spriteEffect_current;

        Texture2D cutSceneSprite;
        Texture2D playerSprite;
        Texture2D textureChar;
        Texture2D flashlight_horizontal;
        Texture2D flashlight_vertical;
        Texture2D flashlight_current;

        Facing current_facing = Facing.UP;

        public Vector2 position;
        Vector2 oldPosition;
        Vector2 velocity;
        Vector2 tileSize;
        Vector2 lightOffset;
        const float MOVING_VELOCITY = 2.5f;
        int x_index, y_index;

        bool goingRight = false; //controls movement to the right
        bool goingLeft = false; //controls movement to the left
        bool goingUp = false; //controls movement up
        bool goingDown = false; //controls movement down
        bool moving = false; //prevents character from moving in multiple directions
        bool light = true;
   
        float elapsed;
        float alpha = 0.0f;
        Rectangle sprite = new Rectangle(0, 0, 85, 110);
        const int spriteHeight = 110;
        const int spriteWidth = 85;

        public Player(Texture2D cutSceneSprite, Texture2D textureChar, Texture2D flashlight_horizontal, Texture2D flashlight_vertical, Vector2 tileSize)
        {
            this.cutSceneSprite = cutSceneSprite;
            this.playerSprite = textureChar;

            this.textureChar = playerSprite;
            this.flashlight_horizontal = flashlight_horizontal;
            this.flashlight_vertical = flashlight_vertical;
            this.tileSize = tileSize;

            position = new Vector2(x_index * tileSize.X, y_index * tileSize.Y);
            keyboard_old = Keyboard.GetState();

            flashlight_current = flashlight_vertical;
        }

        public void Update(GameTime gameTime, ref int[,] map, ref Navigation.RoomNavigator roomNav)
        {
            KeyboardState keyboard = Keyboard.GetState();

            if (keyboard.IsKeyDown(Keys.L) && !keyboard_old.IsKeyDown(Keys.L))
                toggleLight();

            #region Up
            if (moving == false)
            {
                if (keyboard.IsKeyDown(Keys.W))
                {
                    oldPosition.Y = position.Y;

                    current_facing = Facing.UP;

                    if (map[x_index, y_index - 1] == 0)
                    {
                        velocity.Y = -MOVING_VELOCITY;
                        goingUp = true;
                        moving = true;
                    }
                    else if (map[x_index, y_index - 1] == 2)
                    {
                        roomNav.SwitchRooms(this.current_facing, this.x_index, this.y_index);
                    }
                }
            }
            #endregion
            #region Down
            if (moving == false)
            {
                if (keyboard.IsKeyDown(Keys.S))
                {
                    oldPosition.Y = position.Y;

                    current_facing = Facing.DOWN;

                    if (map[x_index, y_index + 1] == 0)
                    {
                        velocity.Y = MOVING_VELOCITY;
                        goingDown = true;
                        moving = true;
                    }
                    else if (map[x_index, y_index + 1] == 2)
                    {
                        roomNav.SwitchRooms(this.current_facing, this.x_index, this.y_index);
                    }
                }
            }
            #endregion
            #region Left
            if (moving == false)
            {
                if (keyboard.IsKeyDown(Keys.A))
                {
                    oldPosition.X = position.X;

                    current_facing = Facing.LEFT;

                    if (map[x_index - 1, y_index] == 0)
                    {
                        velocity.X = -MOVING_VELOCITY;
                        goingLeft = true;
                        moving = true;
                    }
                    else if (map[x_index - 1, y_index] == 2)
                    {
                        roomNav.SwitchRooms(this.current_facing, this.x_index, this.y_index);
                    }
                }
            }
            #endregion
            #region Right
            if (moving == false)
            {
                if (keyboard.IsKeyDown(Keys.D))
                {
                    oldPosition.X = position.X;

                    current_facing = Facing.RIGHT;

                    if (map[x_index + 1, y_index] == 0)
                    {
                        velocity.X = MOVING_VELOCITY;
                        goingRight = true;
                        moving = true;
                    }
                    else if (map[x_index + 1, y_index] == 2)
                    {
                        roomNav.SwitchRooms(this.current_facing, this.x_index, this.y_index);
                    }
                }
            }
            #endregion

            keyboard_old = keyboard;

            if (goingRight == true)
            {
                if (position.X >= oldPosition.X + tileSize.X)
                {
                    velocity.X = 0;
                    goingRight = false;
                    //characterIndex += 1;
                    x_index += 1;
                    moving = false;
                }
            }
            else if (goingLeft == true)
            {
                if (position.X <= oldPosition.X - tileSize.X)
                {
                    velocity.X = 0;
                    goingLeft = false;
                    //characterIndex -= 1;
                    x_index -= 1;
                    moving = false;
                }
            }
            else if (goingDown == true)
            {
                if (position.Y >= oldPosition.Y + tileSize.Y)
                {
                    velocity.Y = 0;
                    goingDown = false;
                    //characterIndex += rowCount;
                    y_index += 1;
                    moving = false;
                }
            }
            else if (goingUp == true)
            {
                if (position.Y <= oldPosition.Y - tileSize.Y)
                {
                    velocity.Y = 0;
                    goingUp = false;
                    //characterIndex -= rowCount;
                    y_index -= 1;
                    moving = false;
                }
            }

            position += velocity;

            switch (current_facing)
            {
                case Facing.RIGHT:
                    flashlight_current = flashlight_horizontal;
                    lightOffset.X = -15;
                    lightOffset.Y = 14;
                    spriteEffect_current = SpriteEffects.None;
                    break;
                case Facing.LEFT:
                    flashlight_current = flashlight_horizontal;
                    lightOffset.X = 20;
                    lightOffset.Y = 14;
                    spriteEffect_current = SpriteEffects.FlipHorizontally;
                    break;
                case Facing.UP:
                    flashlight_current = flashlight_vertical;
                    lightOffset.X = -15;
                    lightOffset.Y = 20;
                    spriteEffect_current = SpriteEffects.None;
                    break;
                case Facing.DOWN:
                    flashlight_current = flashlight_vertical;
                    lightOffset.X = 15;
                    lightOffset.Y = -5;
                    spriteEffect_current = SpriteEffects.FlipVertically;
                    break;

            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (light == true)
            {//0.983
                spriteBatch.Draw(flashlight_current, position + tileSize/2, new Rectangle(0, 0, 1700, 1700), Color.White, 0, new Vector2(850 + lightOffset.X, 850 + lightOffset.Y), 1.0f, spriteEffect_current, 0);
            }

                spriteBatch.Draw(flashlight_current, Vector2.Zero, new Rectangle(0, 0, 1700, 1700), Color.White * alpha, 0, new Vector2(850, 850), 1.0f, spriteEffect_current, 0);
            

            spriteBatch.Draw(textureChar, position - new Vector2(0, 25), sprite, Color.White, 0, new Vector2(0, 2), 1.0f, SpriteEffects.None, 0);

        }

        public void toggleLight()
        {
            if (light == true)
                light = false;
            else if (light == false)
                light = true;
        }

        public void setLight(bool b)
        {
            light = b;
        }

        public void setPosition(int x, int y)
        {
            x_index = x;
            y_index = y;
            position = new Vector2(x_index * tileSize.X, y_index * tileSize.Y);
        }

        public void incrementLocation(Vector2 velocity)
        {
            position += velocity;
        }

        public int getXIndex()
        {
            return x_index;
        }

        public int getYIndex()
        {
            return y_index;
        }

        public Vector2 getLocation()
        {
            return position;
        }

        public float getVelocity()
        {
            return MOVING_VELOCITY;
        }

        public Facing getFacing()
        {
            return current_facing;
        }

        public bool getLight()
        {
            return light;
        }

        public void setFacing(Facing new_facing)
        {
            current_facing = new_facing;
        }

        public void setXIndex(int i)
        {
            x_index = i;
        }

        public void setYIndex(int i)
        {
            y_index = i;
        }

        public void setCharTexture(Texture2D charText, int spriteX, int spriteY)
        {
            this.textureChar = charText;
            this.sprite.X = spriteX;
            this.sprite.Y = spriteY;
        }

        public void spriteMove(GameTime gameTime)
        {  
            elapsed += (float)gameTime.ElapsedGameTime.Milliseconds;
            switch (current_facing)
            {
                case Facing.DOWN:
                    sprite.Y = spriteHeight * 0;
                    break;
                case Facing.UP:
                    sprite.Y = spriteHeight * 1;
                    break;
                case Facing.RIGHT:
                    sprite.Y = spriteHeight * 2;
                    break;
                case Facing.LEFT:
                    sprite.Y = spriteHeight * 3;
                    break;
            }

            if (moving && (elapsed > 120))
            {
                sprite.X += spriteWidth;
                if (sprite.X >= spriteWidth*6) { sprite.X = 0; }
                elapsed = 0;
            }

            if (!moving && (elapsed > 121)) { sprite.X = spriteWidth * 5; elapsed = 0; }
        }

        public void WalkInCutScene(bool b, Facing facing, int x, int y)
        {
            if (b)
            {
                this.light = false;
                this.current_facing = facing;
                this.setPosition(x, y);
                moving = true;
            }
            else
            {
                this.light = true;
                this.current_facing = facing;
                this.setPosition(x, y);
                moving = false;
            }
        }

        public void EndCutScene(bool b, int i)
        {
            if (b && i == 1)
            {
                textureChar = cutSceneSprite;
                sprite.Y = 110;
                sprite.X = 0;
            }
            else if (b && i == 2)
            {
                textureChar = cutSceneSprite;
                sprite.Y = 110;
                sprite.X = 3 * 85;
            }
            else
            {
                textureChar = playerSprite;
                sprite.Y = 0;
                sprite.X = 3 * 85;
            }

        }

        public float alphaFlash(Enemy enemy, float energy)
        {
            if (Math.Abs(enemy.getShadeX() * 85 - position.X) > 200.0f || Math.Abs(enemy.getShadeY() * 85 - position.Y) > 200.0f)
            {
                alpha = 1.0f-energy;
                return (energy + 0.0005f);
            }
            else
            {
                /*
                if(Math.Abs(enemy.position.X - position.X) > Math.Abs(enemy.position.Y - position.Y))
                    alpha += (Math.Abs(enemy.position.X - position.X) / 300.0f);
                else
                    alpha += (Math.Abs(enemy.position.X - position.X) / 300.0f);
                */
                alpha += 0.05f;
                 if (alpha >= 1)
                    alpha = 1.0f - energy;//(Math.Abs(enemy.position.X - position.X) / 300.0f);
                 return (energy - 0.001f);
            }
        }
    }
}
